package cn.com.huzo.webapp.controller.trade;

import cn.com.huzo.model.entities.trade.ShippingOrderHeaderEntity;
import huzofw.common.web.controller.BaseFormController;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import cn.com.huzo.service.trade.ShippingOrderHeaderManager;
import cn.com.huzo.service.trade.ShippingOrderLinesDoManager;
import cn.com.huzo.service.trade.ShippingOrderLinesManager;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

/**
 * 发货单画面控制器
 *
 * @author 吴旭
 */
@Controller
@RequestMapping(value = "/trade")
public class ShippingOrderController extends BaseFormController {

    // <editor-fold defaultstate="collapsed" desc="属性">
    @Resource(name = "ShippingOrderHeaderManager")
    private ShippingOrderHeaderManager _manager_header;

    @Resource(name = "ShippingOrderLinesDoManager")
    private ShippingOrderLinesDoManager _manager_lines_do;

    @Resource(name = "ShippingOrderLinesManager")
    private ShippingOrderLinesManager _manager_lines;

    @Resource(name = "freemarkerConfig")
    private FreeMarkerConfigurer freemarkerConfig;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="画面处理部分">
    /**
     * 跳转到发货单一览画面
     * <p>
     * @param request 上下文请求
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping("/shipping_order/list.html")
    public ModelAndView redirectListWnd(HttpServletRequest request) throws Exception {
        ModelAndView view = new ModelAndView();
        view.setViewName("trade.shipping_order.list.def");
        return view;
    }

    /**
     * 跳转发货单编辑画面
     * <p>
     * @param request 上下文请求
     * @param action 操作标志 1;增加 2：编辑
     * @param headerId 发货单标识
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping("/shipping_order/{action}/{headerId}/edit.html")
    public ModelAndView redirectEditWnd(HttpServletRequest request, @PathVariable(value = "action") int action,
            @PathVariable(value = "headerId") Long headerId) throws Exception {
        ModelAndView view = new ModelAndView();
        view.addObject("action", action);
        view.addObject("headerId", headerId.toString());
        view.setViewName("trade.shipping_order.edit.def");
        return view;
    }

    /**
     * 批量更改发货箱装画面
     * <p>
     * @return
     */
    @RequestMapping("/shipping_order/lines_do/incase/edit.html")
    public ModelAndView redirectShippingOrderLinesDoInCaseEditWnd() {
        ModelAndView view = new ModelAndView();
        view.setViewName("popup.trade.shipping_order_lines_do_incase.edit.def");
        return view;
    }

    /**
     * 发货单-打印预览画面
     * <p>
     * @return
     */
    @RequestMapping("/shipping_order/print.html")
    public ModelAndView redirectPrintPreviewWnd() {
        ModelAndView view = new ModelAndView();
        view.setViewName("print.trade.shipping_order.print.def");
        return view;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="主表处理部分">
    /**
     * 得到新的单据号
     * <p>
     * @return @throws Exception
     */
    @RequestMapping(value = "/shipping_order/header/fetchNewBillNo.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchNewBillNo() throws Exception {
        Map<String, Object> rtnVal = new HashMap();
        rtnVal.put("BillNo", _manager_header.fetchNewBillNo());
        return rtnVal;
    }

    /**
     * 根据ID取得发货单数据。
     *
     * @param criterion 发货单ID、当前用户、流程标识
     * @return 发货发令单数据。
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/shipping_order/header/fetchByKey.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchByKey(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_header.fetchByHeaderId(criterion);
    }

    /**
     * 根据条件取得发货单信息分页数据。
     * <p>
     * @param criterion 检索条件
     * @return 分页数据
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/header/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchForPage(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_header.fetchForPage(criterion);
    }

    /**
     * 保存发货单信息数据。
     * <p>
     * @param instance 要保存的数据
     * @return 新增记录主键.
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/header/save.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Long save(@RequestBody final ShippingOrderHeaderEntity instance) throws Exception {
        Long rowsAffected;

        if (instance.getHeaderId() > 0) { //编辑
            rowsAffected = (long) _manager_header.update(instance);
        } else {//新增
            rowsAffected = _manager_header.insert(instance);
        }

        return rowsAffected;
    }

    /**
     * 删除发货单信息。
     *
     * @param criterion 要删除的数据
     * @return 返回删除后的数据
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/shipping_order/header/delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> delete(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_header.delete(criterion);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="发货款号明细处理部分">
    /**
     * 取得该发货单的箱号信息。
     * <p>
     * @param criterion 检索条件
     * @return 分页数据
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines_do/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchDoLinesForPage(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines_do.fetchForPage(criterion);
    }

    /**
     * 引入发货款号明细同时增加发货单明细数据。
     * <p>
     * @param criterion 要保存的分配明细。
     * @return 影响的行数（引入的发货发令单明细记录）。
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines_do/insert.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> batchInsertDo(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines_do.insert(criterion);
    }

    /**
     * 更新引入的款号明细同时更新发货单明细数据。
     * <p>
     * @param criterion 要保存的分配明细。
     * @return 更新后的发令单及发货明细）。
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines_do/update.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> batchUpdateDo(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines_do.update(criterion);
    }

    /**
     * 批量更新发货箱装并重新计算发货明细。
     * <p>
     * @param criterion 要更新的数据发货数据。
     * @return 更新后的发令单及发货明细
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines_do/batch_update_incase.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> batchUpdateLinesDoInCase(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines_do.update(criterion);
    }

    /**
     * 删除发货款号明细。
     *
     * @param criterion 删除条件
     * @return 影响行数
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/shipping_order/lines_do/delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> deleteLinesDo(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines_do.delete(criterion);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="明细处理部分">
    /**
     * 根据主记录ID得到全部明细数据列表
     *
     * @param headerId 主记录ID
     * @return 全部明细数据列表
     * @throws java.lang.Exception
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/shipping_order/lines/fetchAll.html",
            method = RequestMethod.POST,
            produces = {"application/xml", "application/json"})
    public @ResponseBody
    Map<String, Object> fetchLinesByHeaderKey(@RequestBody final Long headerId) throws Exception {
        return _manager_lines.fetchByHeaderId(headerId);
    }

    /**
     * 取得该发货单的箱号信息。
     * <p>
     * @param criterion 检索条件
     * @return 分页数据
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchLinesForPage(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines.fetchForPage(criterion);
    }

    /**
     * 更新发货单明细信息数据。
     * <p>
     * @param criterion 要更新的数据。
     * @return 影响的行数。
     * @throws Exception
     */
    @RequestMapping(value = "/shipping_order/lines/save.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> saveLines(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines.save(criterion);
    }

    /**
     * 删除发货单明细信息。
     *
     * @param criterion 删除条件
     * @return 影响行数
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/shipping_order/lines/delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> deleteLines(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_lines.delete(criterion);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="打印处理部分">
    /**
     * 取得打印数据
     *
     * @param headerId 发货单ID
     * @return 打印数据
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/shipping_order/print/fetch.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchPrintData(@RequestBody final Long headerId) throws Exception {
        return _manager_header.fetchPrintData(headerId);
    }

    /**
     * 导出发货明细excel文件
     *
     * @param response 客户端响应
     * @param request 客户端请求
     * @throws IOException
     */
    @RequestMapping(value = "/shipping_order/export_to_excel.html", method = RequestMethod.POST)
    public void exportToExcel(HttpServletResponse response, HttpServletRequest request) throws Exception {
        long _headerId = Long.parseLong(request.getParameter("_ExportHeaderId").trim());
        int _exportFlag = Integer.parseInt(request.getParameter("_ExportFlag").trim());

        String filename = "发货明细表.xls";
        String tempFilePath = request.getServletContext().getRealPath("/") + "/WEB-INF/templates/01_trade/";

        if (_exportFlag == 1) {
            Map<String, Object> data = _manager_header.fetchPrintData(_headerId);
            try (OutputStream out = response.getOutputStream()) {
                response.reset();                                                   // 清空输出流
                response.setHeader("Content-disposition", "attachment; filename="
                        + new String(filename.getBytes("GB2312"), "ISO8859-1"));    // 设定输出文件头
                response.setContentType("application/msexcel");                     // 定义输出类型

                /**
                 * **********创建工作簿************
                 */
                parse("01_trade/发货明细表.ftl", data, out);
                out.flush();
            }
        }
        if (_exportFlag == 2) {
            Map<String, Object> data = _manager_header.fetchPrintData02(_headerId);
            try (OutputStream out = response.getOutputStream()) {
                response.reset();                                                   // 清空输出流
                response.setHeader("Content-disposition", "attachment; filename="
                        + new String(filename.getBytes("GB2312"), "ISO8859-1"));    // 设定输出文件头
                response.setContentType("application/msexcel");                     // 定义输出类型

                /**
                 * **********创建工作簿************
                 */
                parse("01_trade/发货明细表02.ftl", data, out);
                out.flush();
            }
        }
        if (_exportFlag == 3) {
            Map<String, Object> data = _manager_header.fetchPrintData03(_headerId);
            try (OutputStream out = response.getOutputStream()) {
                response.reset();                                                   // 清空输出流
                response.setHeader("Content-disposition", "attachment; filename="
                        + new String(filename.getBytes("GB2312"), "ISO8859-1"));    // 设定输出文件头
                response.setContentType("application/msexcel");                     // 定义输出类型

                /**
                 * **********创建工作簿************
                 */
                parse("01_trade/发货明细表03.ftl", data, out);
                out.flush();
            }
        }
    }

    private void parse(String templateName, Map<String, Object> data, OutputStream out) throws IOException, TemplateException {
        try (OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8")) {
            Configuration cfg = freemarkerConfig.getConfiguration();
            //cfg.setDirectoryForTemplateLoading(new File(templateFileDirectory));
            // 加载模板
            Template template = cfg.getTemplate(templateName, "utf-8");
            // 填充数据至Excel
            template.process(data, writer);
            writer.flush();
        }
    }
    // </editor-fold>
}
